package com.zslibrary.BusMaster;

import com.zslibrary.Enum.BoardId;
import com.zslibrary.Enum.NFCMessageId;
import com.zslibrary.Enum.StateDefine;
import com.zslibrary.Pipe.Pipe;
import com.zslibrary.Protocol.NFCIdleState;
import com.zslibrary.Protocol.Poll;
import com.zslibrary.Protocol.UserCommand;
import com.zslibrary.StateHandle.ErrorState;
import com.zslibrary.StateHandle.IdleState;
import com.zslibrary.StateHandle.InitState;
import com.zslibrary.StateHandle.NFCErrorState;
import com.zslibrary.StateHandle.NFCReconnectState;
import com.zslibrary.StateHandle.ReconnectState;
import com.zslibrary.StateHandle.StateMachine;
import com.zslibrary.Structure.CardStruct;
import com.zslibrary.Structure.ErrorStruct;
import com.zslibrary.Structure.MessageStruct;
import com.zslibrary.Tools.FrameBuilder;
import com.zslibrary.Tools.ZSLog;

public class BusNfc {
    private static BusNfc mInstance;
//    private static StreamPipe mPipe;
    private static  Pipe mPipeLine;
//    private Thread runTimeThread;
//    private Boolean setBusErrorFlag=false;
//    private Boolean clearBusErrorFlag=false;
//    private long reconnectionTime;
    private OnDetectCard mOnDetectCard;
    private static CardStruct mCurrentCardInfo=new CardStruct();
    private StateMachine mStateMachine;

    public void startNfcBus(){
//        mPipe.setAsyncMessageHandler(new StreamPipe.AsyncMessageHandler() {
//            @Override
//            public void handleAsyncMessages(MessageStruct[] messages) {
//                for(MessageStruct msg: messages) {
//                    if (msg == null) {
//                        break;
//                    }
//                    switch(msg.messageId){
//                        case NFCMessageId.MSG_DETECTED_CARD:{
//                            FrameBuilder builder=new FrameBuilder(msg.messageData);
//                            CardStruct cardData=new CardStruct();
//                            cardData.cardSN=builder.popData(4);
//                            cardData.value=builder.popData(4);
//                            ZSLog.d("detected card SN:"+String.valueOf(cardData.cardSN));
//                            if(mOnDetectCard!=null){
//                                mCurrentCardInfo=cardData;
//                                mOnDetectCard.onDetectCard(cardData);
//                            }
//                        }break;
//
//                        default:
//                            mPipe.putAsyncMessage(msg);
//                            break;
//                    }
//                }
//            }
//        });
//        if(mPipe.launchPipe("/dev/ttyS0", BoardId.NFC_BOARD,9600)){
//            runTimeThread=new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    while(true){
//                        if(runTimeThread.isInterrupted()){
//                            break;
//                        }
//                        SystemClock.sleep(100);
//                        if (mPipe.getPipeExceptionCounter() >= 10) {
//                            clearBusErrorFlag=false;
//                            ErrorStruct error = new ErrorStruct();
//                            error.errorCode = "EOD";
//                            error.isFatal = false;
//                            error.isPersistent = true;
//                            HandleError.setError(error);
//                            reconnectionTime= SystemClock.currentThreadTimeMillis();
//                        }else{
//                            if(mPipe.getPipeExceptionCounter()>=1){
//                                reconnectionTime= SystemClock.currentThreadTimeMillis();
//                            }else{
//                                if((SystemClock.currentThreadTimeMillis()-reconnectionTime)>3000){
//                                    if(!clearBusErrorFlag){
//                                        clearBusErrorFlag=true;
//                                        HandleError.clearError("EOD");
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            });
//            runTimeThread.start();
//        }
        if(mPipeLine.launchPipe("/dev/ttyS0",BoardId.NFC_BOARD,9600)){
            mStateMachine=new StateMachine();
            mStateMachine.registerState(StateDefine.STATE_IDLE,new NFCIdleState(mPipeLine));
            mStateMachine.registerState(StateDefine.STATE_ERROR,new NFCErrorState(mPipeLine,new ErrorStruct("EOD",false,false)));
            mStateMachine.registerState(StateDefine.STATE_RECONNECT,new NFCReconnectState(mPipeLine,"EOD"));
            mStateMachine.startStateMachine();
            Poll.setPollHandle(new Poll.NFCPollHandle() {
                @Override
                public void handler(MessageStruct message) {
                    switch(message.messageId) {
                        case NFCMessageId.MSG_DETECTED_CARD: {
                            FrameBuilder builder = new FrameBuilder(message.messageData);
                            CardStruct cardData = new CardStruct();
                            cardData.cardSN = builder.popData(4);
                            cardData.value = builder.popData(4);
                            //ZSLog.d("detected card SN:"+cardData.cardSN);
                            if (mOnDetectCard != null) {
                                mCurrentCardInfo = cardData;
                                mOnDetectCard.onDetectCard(cardData);
                            }
                        }
                        break;

                        default:
                            break;
                    }
                }
            });
        }
    }

    public static BusNfc getInstance(){
        if(mInstance==null){
            mInstance=new BusNfc();
//            mPipe=new StreamPipe();
            mPipeLine=new Pipe();
        }
        return mInstance;
    }

    public interface OnDetectCard{
        void onDetectCard(CardStruct cardData);
    }

    public void setOnDetectCard(OnDetectCard onDetectAction){
        mOnDetectCard=onDetectAction;
    }

    public CardStruct getCardInfo(){
        CardStruct returnInfo=new CardStruct();
        returnInfo=mCurrentCardInfo;
        return returnInfo;
    }
}
